{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义模型\n",
    "\n",
    "定义一个三层的全连接网络（FCN），也叫多层感知机（MLP）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "class Model(nn.Module):\n",
    "    def __init__(self, state_dim, action_dim,hidden_dim=128):\n",
    "        \"\"\" 初始化q网络，为全连接网络\n",
    "        \"\"\"\n",
    "        super(Model, self).__init__()\n",
    "        self.fc1 = nn.Linear(state_dim, hidden_dim) # 输入层\n",
    "        self.fc2 = nn.Linear(hidden_dim,hidden_dim) # 隐藏层\n",
    "        self.fc3 = nn.Linear(hidden_dim, action_dim) # 输出层\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # 各层对应的激活函数\n",
    "        x = F.relu(self.fc1(x)) \n",
    "        x = F.relu(self.fc2(x))\n",
    "        return self.fc3(x)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义经验回放\n",
    "\n",
    "经验回放主要有两个功能，一是存储样本(push)，二是随时采样样本(sample)。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import deque\n",
    "import random\n",
    "\n",
    "class ReplayBuffer(object):\n",
    "    def __init__(self, capacity: int) -> None:\n",
    "        self.capacity = capacity\n",
    "        self.buffer = deque(maxlen=self.capacity)\n",
    "    def push(self,transitions):\n",
    "        ''' 存储transition到经验回放中\n",
    "        '''\n",
    "        self.buffer.append(transitions)\n",
    "    def sample(self, batch_size: int, sequential: bool = False):\n",
    "        if batch_size > len(self.buffer): # 如果批量大小大于经验回放的容量，则取经验回放的容量\n",
    "            batch_size = len(self.buffer)\n",
    "        if sequential: # 顺序采样\n",
    "            rand = random.randint(0, len(self.buffer) - batch_size)\n",
    "            batch = [self.buffer[i] for i in range(rand, rand + batch_size)]\n",
    "            return zip(*batch)\n",
    "        else: # 随机采样\n",
    "            batch = random.sample(self.buffer, batch_size)\n",
    "            return zip(*batch)\n",
    "    def __len__(self):\n",
    "        ''' 返回当前存储的量\n",
    "        '''\n",
    "        return len(self.buffer)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义策略\n",
    "\n",
    "\n",
    "智能体主要负责与环境交互并更新策略(模型参数)，因此首先需要定义sample_action和predict_action两个函数，前者用于训练时的采样动作，一般会采取$\\varepsilon-\\text{greedy}$策略来提高探索能力，后者一般用于测试算法时的预测动作。其次需要定义update函数，这个函数主要用来从经验回放中采样样本，然后更新模型参数。\n",
    "\n",
    "注意：\n",
    "* 每个张量的维度要对应上，否则可能会报错或者不收敛"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import random\n",
    "import torch\n",
    "import torch.optim as optim\n",
    "import math\n",
    "import numpy as np\n",
    "class Policy:\n",
    "    def __init__(self,cfg):\n",
    "        self.target_update = cfg.target_update\n",
    "        self.action_dim = cfg.action_dim  \n",
    "        self.device = torch.device(cfg.device) \n",
    "        self.gamma = cfg.gamma # 奖励的折扣因子\n",
    "        # e-greedy策略相关参数\n",
    "        self.sample_count = 0  # 用于epsilon的衰减计数\n",
    "        self.epsilon_start = cfg.epsilon_start\n",
    "        self.epsilon_end =cfg.epsilon_end\n",
    "        self.epsilon_decay = cfg.epsilon_decay\n",
    "        self.batch_size = cfg.batch_size\n",
    "        self.memory = ReplayBuffer(cfg.buffer_size)\n",
    "        # 当前网络和目标网络\n",
    "        self.policy_net = Model(cfg.state_dim, cfg.action_dim, hidden_dim = cfg.hidden_dim).to(self.device)\n",
    "        self.target_net = Model(cfg.state_dim, cfg.action_dim, hidden_dim = cfg.hidden_dim).to(self.device)\n",
    "        # 复制参数到目标网络\n",
    "        for target_param, param in zip(self.target_net.parameters(),self.policy_net.parameters()): \n",
    "            target_param.data.copy_(param.data)\n",
    "        self.optimizer = optim.Adam(self.policy_net.parameters(), lr=cfg.lr) # 优化器\n",
    "        self.update_cnt = 0 # 用于延迟更新目标网络的计数\n",
    "    def sample_action(self, state):\n",
    "        ''' 采样动作\n",
    "        '''\n",
    "        self.sample_count += 1\n",
    "        # epsilon指数衰减\n",
    "        self.epsilon = self.epsilon_end + (self.epsilon_start - self.epsilon_end) * \\\n",
    "            math.exp(-1. * self.sample_count / self.epsilon_decay) \n",
    "        if random.random() > self.epsilon:\n",
    "            with torch.no_grad():\n",
    "                state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0)\n",
    "                q_values = self.policy_net(state)\n",
    "                action = q_values.max(1)[1].item() # choose action corresponding to the maximum q value\n",
    "        else:\n",
    "            action = random.randrange(self.action_dim)\n",
    "        return action\n",
    "    @torch.no_grad() # 不计算梯度，该装饰器效果等同于with torch.no_grad()：\n",
    "    def predict_action(self, state):\n",
    "        ''' 预测动作\n",
    "        '''\n",
    "        state = torch.tensor(state, device=self.device, dtype=torch.float32).unsqueeze(dim=0)\n",
    "        q_values = self.policy_net(state)\n",
    "        action = q_values.max(1)[1].item() # choose action corresponding to the maximum q value\n",
    "        return action\n",
    "    def update(self):\n",
    "        if len(self.memory) < self.batch_size: # 当经验回放中不满足一个批量时，不更新策略\n",
    "            return\n",
    "        # 从经验回放中随机采样一个批量的样本\n",
    "        states, actions, rewards, next_states, dones = self.memory.sample(\n",
    "            self.batch_size)\n",
    "        # 将数据转换为tensor\n",
    "        states = torch.tensor(np.array(states), device=self.device, dtype=torch.float) # [batch_size, state_dim]\n",
    "        actions = torch.tensor(actions, device=self.device).unsqueeze(1)  #  [batch_size, 1]\n",
    "        rewards = torch.tensor(rewards, device=self.device, dtype=torch.float).unsqueeze(1)   # [batch_size, 1]\n",
    "        next_states = torch.tensor(np.array(next_states), device=self.device, dtype=torch.float) # [batch_size, state_dim]\n",
    "        dones = torch.tensor(np.float32(dones), device=self.device).unsqueeze(1)  # [batch_size,1]\n",
    "        # 计算当前状态(s_t,a)对应的Q值\n",
    "        q_values = self.policy_net(states).gather(dim=1, index=actions) \n",
    "        # 计算下一时刻的状态(s_t_,a)对应的Q值，注意需要detach()，因为不需要计算梯度\n",
    "        next_q_values_max = self.target_net(next_states).max(1)[0].detach().unsqueeze(1)\n",
    "        # 计算期望的Q值，对于终止状态，此时dones[0]=1, 对应的expected_q_value等于reward\n",
    "        expected_q_values = rewards + self.gamma * next_q_values_max * (1-dones) # [batch_size, 1]\n",
    "         # 计算均方根损失\n",
    "        loss = nn.MSELoss()(q_values, expected_q_values) \n",
    "        # 优化更新模型\n",
    "        self.optimizer.zero_grad()  \n",
    "        loss.backward()\n",
    "        # clip防止梯度爆炸\n",
    "        for param in self.policy_net.parameters():  \n",
    "            param.grad.data.clamp_(-1, 1)\n",
    "        self.optimizer.step() \n",
    "        self.update_cnt += 1\n",
    "        # 每隔一定步数更新目标网络的参数\n",
    "        if self.update_cnt % self.target_update == 0:\n",
    "            for target_param, param in zip(self.target_net.parameters(),self.policy_net.parameters()): \n",
    "                target_param.data.copy_(param.data)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "import gymnasium as gym\n",
    "\n",
    "def train(cfg):\n",
    "    ''' 训练\n",
    "    '''\n",
    "    env = gym.make(cfg.env_id)\n",
    "    setattr(cfg, \"action_space\", env.action_space)\n",
    "    setattr(cfg, \"state_dim\", env.observation_space.shape[0])\n",
    "    setattr(cfg, \"action_dim\", env.action_space.n)\n",
    "    policy = Policy(cfg)\n",
    "    rewards = []  # 记录所有回合的奖励\n",
    "    frames = []\n",
    "    for i_ep in range(cfg.train_eps):\n",
    "        ep_reward = 0  # 记录一回合内的奖励\n",
    "        ep_step = 0\n",
    "        state, info = env.reset(seed = cfg.seed)  # 重置环境，返回初始状态\n",
    "        for _ in range(cfg.max_steps):\n",
    "            ep_step += 1\n",
    "            action = policy.sample_action(state)  # 选择动作\n",
    "            next_state, reward, terminated, truncated , info = env.step(action)  # 更新环境，返回transition\n",
    "            policy.memory.push((state, action, reward, next_state, terminated))  # 保存transition\n",
    "            state = next_state  # 更新下一个状态\n",
    "            policy.update()  # 更新智能体\n",
    "            ep_reward += reward  # 累加奖励\n",
    "            if terminated:\n",
    "                break\n",
    "        rewards.append(ep_reward)\n",
    "        frames.append(i_ep)\n",
    "        if (i_ep + 1) % 10 == 0:\n",
    "            print(f\"回合：{i_ep+1}/{cfg.train_eps}，奖励：{ep_reward:.2f}，Epislon：{policy.epsilon:.3f}\")\n",
    "    env.close()\n",
    "    return {'rewards':rewards, 'frames':frames}\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 设置参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Config:\n",
    "    def __init__(self) -> None:\n",
    "        self.algo_name = 'DQN' # 算法名称\n",
    "        self.env_id = 'CartPole-v1' # 环境id\n",
    "        self.mode = 'train'\n",
    "        self.seed = 1 # 随机种子，便于复现，0表示不设置\n",
    "        self.train_eps = 100 # 训练的回合数\n",
    "        self.test_eps = 20 # 测试的回合数\n",
    "        self.max_steps = 200 # 每个回合的最大步数，超过该数则游戏强制终止\n",
    "        self.gamma = 0.95 # 折扣因子\n",
    "        self.epsilon_start = 0.95 # e-greedy策略中初始epsilon\n",
    "        self.epsilon_end = 0.01 # e-greedy策略中的终止epsilon\n",
    "        self.epsilon_decay = 500 # e-greedy策略中epsilon的衰减率\n",
    "        self.buffer_size = 100000 # 经验回放池的容量\n",
    "        self.hidden_dim = 256 # 神经网络的隐藏层维度\n",
    "        self.batch_size = 64 # 批次大小\n",
    "        self.target_update = 100 # 目标网络的更新频率\n",
    "        self.lr = 0.0001 # 学习率\n",
    "        self.device = 'cpu' if not torch.cuda.is_available() else 'cuda'"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 开始训练"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hyperparameters:\n",
      "================================================================================\n",
      "        Name        \t       Value        \t        Type        \n",
      "     algo_name      \t        DQN         \t   <class 'str'>    \n",
      "       env_id       \t    CartPole-v1     \t   <class 'str'>    \n",
      "        mode        \t       train        \t   <class 'str'>    \n",
      "        seed        \t         1          \t   <class 'int'>    \n",
      "     train_eps      \t        100         \t   <class 'int'>    \n",
      "      test_eps      \t         20         \t   <class 'int'>    \n",
      "     max_steps      \t        200         \t   <class 'int'>    \n",
      "       gamma        \t        0.95        \t  <class 'float'>   \n",
      "   epsilon_start    \t        0.95        \t  <class 'float'>   \n",
      "    epsilon_end     \t        0.01        \t  <class 'float'>   \n",
      "   epsilon_decay    \t        500         \t   <class 'int'>    \n",
      "    buffer_size     \t       100000       \t   <class 'int'>    \n",
      "     hidden_dim     \t        256         \t   <class 'int'>    \n",
      "     batch_size     \t         64         \t   <class 'int'>    \n",
      "   target_update    \t        100         \t   <class 'int'>    \n",
      "         lr         \t       0.0001       \t  <class 'float'>   \n",
      "       device       \t        cpu         \t   <class 'str'>    \n",
      "================================================================================\n",
      "回合：10/100，奖励：19.00，Epislon：0.638\n",
      "回合：20/100，奖励：16.00，Epislon：0.490\n",
      "回合：30/100，奖励：16.00，Epislon：0.381\n",
      "回合：40/100，奖励：53.00，Epislon：0.262\n",
      "回合：50/100，奖励：38.00，Epislon：0.158\n",
      "回合：60/100，奖励：52.00，Epislon：0.076\n",
      "回合：70/100，奖励：154.00，Epislon：0.021\n",
      "回合：80/100，奖励：200.00，Epislon：0.010\n",
      "回合：90/100，奖励：200.00，Epislon：0.010\n",
      "回合：100/100，奖励：200.00，Epislon：0.010\n"
     ]
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAioAAAHJCAYAAACrCBICAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAACgjklEQVR4nOzdd3hUVfrA8e+dnt4LEHpvoYNUEQuoCIu6uitiw7Wt8rP3jl1siAgqinWtWFGxo1ho0nuHQHov0+/9/TGZSUJ6MpOE5P08Dw/JnVvOnLmZeeec95yjaJqmIYQQQgjRAumauwBCCCGEENWRQEUIIYQQLZYEKkIIIYRosSRQEUIIIUSLJYGKEEIIIVosCVSEEEII0WJJoCKEEEKIFksCFSGEEEK0WBKoiEpkDkAhREPIe4cIBAlURAU//vgjd9xxh1/OtWzZMnr37k1KSkpAjxFty9KlSxk7dizJycksXLiwyn169+5d4V+/fv0YNWoUV1xxBT///HOVx2iaxhdffMEll1zCSSedxJAhQ5g6dSovvvgiubm5VV5j4sSJFBUVVXosJSWF3r17s2zZshqfy9NPP83IkSMZPHgwn332We1PvgHsdjtLly7lvPPOY9iwYYwcOZJ//etffPbZZ34LLNLS0rjqqqs4evSob9usWbMqvQ4DBgxg4sSJPPTQQ+Tn59frGnfeeSeTJk3yS3nro6ioiEmTJtX6WorAMTR3AUTLsnTpUr+da+LEiXzwwQfEx8cH9BjRdhQVFfHkk08yceJErrjiCpKSkqrd9/zzz+ef//wnAE6nk8zMTD755BOuueYa7rnnHi655BLfvg6HgxtvvJGVK1dy3nnncfnll2OxWNiyZQtvvfUWy5YtY9GiRfTu3bvCNVJTU3niiSd45JFH6v1cdu/ezWuvvcYFF1zA9OnT6datW73PUZusrCyuvPJKUlNTmTVrFsnJyaiqys8//8ydd97JunXrmDt3LoqiNOo6f/zxBytXrqy0vV+/fjzwwAO+351OJ9u2bePZZ59lx44d/O9//2v0tQMpPz+f6667rkIAJpqeBCoiYKKjo4mOjg74MaLtyM/PR1VVTjvtNEaMGFHjvomJiQwePLjCtrPOOosbbriBp556ikmTJvkCnfnz57Ny5UoWL17MuHHjfPuPHj2aGTNmcPHFFzNnzhw+//xzLBaL7/Hw8HA++ugjzjzzTMaOHVuv55KXlwfA2WefzfDhw+t1bF3dcccdpKWl8cEHH9ClSxff9okTJ9K+fXueffZZTjnlFE499dSAXD80NLTSazBixAiKi4uZP38+mzZtqvR4S/Hjjz/y6KOPUlxc3NxFafOk60f4zJo1izVr1rBmzRp69+7N6tWrWb16Nb179+b999/nlFNOYejQofz+++8AfPTRR5x77rkMHjyY5ORkpk+fzjfffOM73/HdOHfeeSeXXXYZn3zyCZMnT2bAgAFMnz6dX3/9tVHHAGzYsIGZM2cyePBgJk6cyJtvvslll13GnXfeWeNz3rhxI1dccQVDhw7lpJNO4uabbyY9Pb3KsnhNmjSpwnl79+7NggULOPfcc0lOTmbBggX07duXd955p8JxOTk59O/f39dqpaoqr7zyCqeffjoDBgxg8uTJvP3227W+ToWFhTz++OOcdtppDBw4kKlTp/Lxxx9XKuP8+fN58sknGTNmDMnJycyePZuDBw/WeG6Hw8Hzzz/PqaeeSnJyMlOnTuXTTz/1PT5r1izuvPNOFi1axJgxYxg2bFilb5xVNdHXtSvk999/56KLLmLYsGGMGjWKW265hdTUVMDzenjPe/fdd1dq3airm266CafT6auzoqIi3nrrLc4777wKQYpXXFwc99xzDwcPHuSrr76q8NiFF15I165duffee6vsAqrOiy++yKxZswC49NJLfc/L7Xbz7rvvcs4555CcnMzEiROZN28edrvdd+ydd97JpZdeygMPPMDQoUM566yzcLvdla6xY8cOVq1axezZsysEKV6XXXYZM2fOJDg42Ldt7dq1zJ49mxEjRjBgwAAmTZrEiy++iKqqQNnr+MYbbzBlyhQGDRrEJ598wl133QXAqaeeWuvfHMCAAQMAOHbsmG/b119/zbnnnsuQIUMYO3Ys999/f63dQx999BFnn322r0vpxRdfrLIuyps8eTJz5syptH369Olce+21ABQUFHD99dczYsQIXnvttVqfjwgsCVSEzwMPPEC/fv3o168fH3zwAf379/c9tmDBAu644w7uv/9+hgwZwrvvvsv999/PaaedxuLFi5k3bx4mk4lbb72VtLS0aq+xdetWlixZwpw5c3jppZfQ6/XccMMNNb4h1XbMvn37uOyyywB49tlnueGGG3jllVdYv359jc93+/btXHzxxdjtdp566ikeeughtm7dyuzZs3G5XPWoOVi0aBHnnHMO8+fPZ/LkyYwcOZLly5dX2Ofbb79F0zTOPvtsAB588EHmz5/PtGnTWLRoEVOmTOGxxx7jpZdeqvY6NpuNiy66iC+//JIrr7yShQsXMmzYMO655x4WLVpUYd+33nqL/fv38/jjj/PII4+wdevWWvOPbr31Vt544w3++c9/+loX7rzzzgof0D/++CPLli3j3nvv5aGHHmLHjh3MmjULq9Varzo73meffcYVV1xBu3btePbZZ7nrrrvYsGEDF154IdnZ2UycOJEFCxYAcO211/LBBx806DrdunWjffv2vvvj999/x263c9ppp1V7zLhx44iMjOSHH36osN1sNvP444+TlpbGU089Vecy/POf/+T+++8H4P777/c9r/vvv98XhL788svMnDmTd955h+uuu65CPsm6detITU3lpZde4pZbbkGv11e6xm+//QZQbV6H2Wzm/vvvZ/To0QDs3LmTyy67jMjISJ577jlefvllhg8fzoIFCyp8AQFPoPWf//yHp556ijFjxvg+4BcsWMB1111X6/M/cOAAAB07dgRg4cKF3HzzzQwePJj58+fz3//+lxUrVjBr1ixsNluV51i8eDH33Xcfo0ePZtGiRcycOZNXX32V++67r8ZrT5s2jZUrV1YILPft28fOnTuZPn06ABaLheXLl/Pkk08SFRVV6/MRgSVdP8KnR48ehIaGAlRqjr3ooouYMmWK7/cjR44we/bsCm9KHTp04Nxzz2X9+vW+D+PjFRYWsmzZMjp16gRAcHAwF198MX/99ReTJ09u0DGLFy8mLCyM1157jaCgIMDzYfSvf/2rxue7aNEiIiMjef311zGbzQDEx8dzyy23sGfPnhqPPd7w4cO5/PLLfb9Pnz6du+++m2PHjtG+fXsAli9fzpgxY4iLi+PAgQN8+OGH3HzzzVx11VWA58NQURQWL17MRRddVOUb5LJly9i9ezfvv/8+Q4YMAWD8+PG4XC4WLlzIv/71LyIjIwFPt8TChQt9H2KHDx/2JYZWde7du3ezYsUK7r77bi699FLA0/Vx9OhRVq9ezdSpUwGwWq0sW7bM9yHTrVs3ZsyYwWeffca///3vetWbl6qqzJs3j3HjxvHMM8/4tntbDJYsWcLtt99O3759AejUqVOjugxiY2PJysoCyr7Vd+jQodr9dTodHTp0qDJXYciQIVx66aW+VoYxY8bUev3ExER69OgBeP7u+vXrx969e/n444+55ZZbfPfE2LFjiY+P5/bbb+fXX3/l5JNPBsDlcvHwww+TmJhY7TW8LVE15fGUt3PnTsaMGcPTTz+NTqfzXf+nn35i9erVFf6mzzzzTM477zzf796/zb59+1a4nqZpFYL+/Px81qxZw8svv8yQIUMYMGAA+fn5vPzyy1xwwQW+4A2gV69ezJw5k08++YSZM2dWKGthYSELFy7kwgsv5N577wXKgsl7772Xyy+/nJ49e1b5PKdNm8aLL77IDz/8wD/+8Q8AvvrqK8LDw31BnclkCkjOkGgYaVERdeL9gPC68847ufXWWykoKGDjxo18/vnnvPvuu4Cn+6A60dHRvjc1wPdGW9O38dqO+euvv5gwYYIvSAHPh0dNHzwA69evZ8KECb4gxXvcTz/9VOn51ub4/c844wzMZjNff/014PnQWL9+ve8b219//YWmaUyaNAmXy+X7N2nSJOx2e7WtQWvWrKFDhw6+IMVr2rRp2O12Nm3a5Ns2cODACt+0a6tr7zXPOOOMCttffPFF5s6d6/t96NChviAFPAmTHTt2ZO3atVWety4OHDhAZmamLxjy6tSpE0OGDGHNmjUNPndVNE2rdxKnTqfzdYEc78Ybb6RLly717gIqz/scjw/yzz77bPR6PatXr/Zti4yMrDFIAXyvfW1dIV7/+Mc/ePXVV3E6nezcuZMVK1Ywf/583G43Tqezwr51/ftYu3Yt/fv39/0bM2YMN998MwMGDOCZZ55BURQ2btyIw+Go9NoPHz6cDh06VPnab9iwAZvNVuXfD3haybxBUvl/mqbRsWNHhg4d6vvbBM+XiClTpmAymer0vETTkhYVUSfl+7HB8+38/vvv588//8RoNNKtWzf69OkD1DyXQvlgAvB9WFT3AVCXY3JycoiJial0XGxsbLXnBE8yY1XHNcTx9RMaGsppp53G8uXLufLKK/n6668JCgrydS+UT6SsijdP5nj5+fnExcVV2u59rgUFBb5tx9eb91tydXXtLVNtdZKQkFBpW0xMTL2Hm1Z17apes9jYWLZv397gc1clLS2NXr16AfhavFJSUujevXuV+2uaRkpKCgMHDqzycYvFwmOPPcbFF1/MU0895WsRqQ9v/R3/+hoMBqKioigsLPRtCwkJqfV83kD92LFjvtab46WnpxMfH4+iKNhsNubOncvnn3+Oy+UiKSmJIUOGYDAYKv1NH3+/V6d///489NBDgOfv1mw2065dO1/LLZQ97+pe+/LP28t7v1RXzxkZGaxZs6bCyC7wdIeOGjWK6dOnM3fuXHJzc0lJSeHQoUM89thjdXpOoulJoCLqTVVVrrrqKoxGIx9//DF9+/bFYDCwd+9ePv/88yYvT2Jioq8Zv7zs7Owam2/DwsLIycmptH3lypX07du32iCqrqMApk2bxlVXXcWhQ4dYvnw5kydP9gUP4eHhALz55ptVfuh4PzyPFxERwaFDhyptz8zMBGhUf7q3TDk5ORW+re/bt4+8vDyGDRsGUOWcIllZWb5WL0VRKn2LLykpqfHa3u6qql7HzMxMv+YJ7N27l8zMTF93wtixY7FYLHz33Xe+rhXwBOORkZGEh4ezdu1acnNzmTBhQrXnHTZsGLNmzeKtt96qNqCpSUREBOB5vuVbA51OZ7XddTXxJgavXLmyykDF5XIxffp0hg4dysKFC3n00UdZsWIFzz//PGPGjPEFI94cloYICQmptS68zzsrK6vS32tmZmaF1jsv7706b968KhOFY2NjCQsLq5Rk3rVrV8DTdfXII4/www8/sH//fjp06OC7v0XLI10/ogLvt+6a5ObmcuDAAc4//3wGDhyIweCJd70jcWpqHQmEESNG8Ntvv1UYGbF9+/ZaJ40bPnw4v//+e4Wuqu3bt3PVVVexbds237e+8snB3g/tuhg3bhyxsbG89dZbbNu2zdft4702eOpy4MCBvn85OTm88MIL1V5jxIgRHD16lA0bNlTY/sUXX2A0GklOTq5T2arifaP+6aefKmyfN28ejz76qO/39evXVwhWtm7dSkpKiu8DLSQkhNzc3AqvR22JzV27diUuLq7SqJojR46wceNGhg4d2rAnVYX58+djsViYMWMG4Gn9uuyyy/j0008rjCZbsmQJ48ePZ9GiRTz44IMkJiZy/vnn13jum2++mU6dOvHkk0/Wu1wjR44EqJSEvXz5ctxud70/SHv27MmECRN49dVXOXLkSKXHFy9eTG5uLtOmTQM8r9GoUaM47bTTfEHK1q1bycnJqfVvui7vG9UZNGgQJpOp0mu/bt06jh07VuVrP2jQIIxGI+np6RX+fgwGA88++ywpKSmEhoZWeGzgwIG+v+nw8HBOOeUUfvzxR1asWMG0adNa9HwubZ20qIgKwsPD2bBhA3/++Sf9+vWrcp+YmBg6dOjAu+++S2JiIuHh4fz222+89dZbQM35JoFwzTXX8PXXX3PllVdyxRVXUFBQwAsvvIBOp6vxzee6667jwgsv5Oqrr+aSSy7BZrPx/PPPk5yczNixY7HZbFgsFp544gn+7//+zzf3g/fbf230ej1nn30277zzDgkJCYwaNcr3WO/evZk2bRr33XcfR48eZcCAARw4cIDnnnuOpKSkKr8lApx77rm89957/Pe//2XOnDkkJSXx008/8cknn3D99df7vmk2RJ8+fZgyZQpPP/00NpuNvn378uuvv/Lzzz/7RqWA5/W98sorufbaaykuLua5556jV69evhyDU045hbfffpt77rmH888/n927d/PGG29UOTLFS6fTcfPNN3PXXXdxyy23MG3aNHJzc1mwYAEREREVEpXrKi0tjY0bNwKe1oP09HQ+/fRTVq1aVSkR9frrr+fgwYNce+21nH/++UyaNImzzjqLw4cP89xzzwHw5JNPVupOO175LqD66tGjBzNmzGD+/PlYrVZGjBjBjh07WLBgAaNGjWL8+PH1PudDDz3EpZdeygUXXMAll1zCoEGDKC4u5ttvv2X58uX861//8iXJJycn88033/C///2P7t27s3PnTl5++WUURan1b9p7333//fdMmDCh2i60qkRGRnLVVVfx0ksvYTQaOeWUU0hJSeGFF17w1cnxoqKiuPLKK3nhhRcoKipi1KhRpKen88ILL6Aoiq8buibTpk1jzpw5uN3uCl8iRMsjgYqoYObMmWzdupX//Oc/PP7449XOEOttKr7zzjsxmUz06NGDl19+mccee4x169b55ohoCp07d2bJkiU89dRTzJkzh5iYGK6++mpefvnlGvvy+/Xrx9tvv80zzzzDjTfeSGhoKCeffDK33norJpMJk8nEiy++yDPPPMN///tfOnTowPXXX1+vqc6nT5/Om2++ydSpUyt963z88cdZvHgx77//PmlpacTExHDWWWdx4403VvuhHhQU5Cuz9026W7duPProo7V+26+Lp59+mgULFvDmm2+Sm5tL9+7dmT9/foWhu8OHD+ekk07innvuATzDX2+//XZfIuLYsWO54447ePvtt1mxYgX9+/dnwYIFtY7COvfccwkJCWHx4sX897//JTQ0lPHjx3PzzTdXmZdTm48//tjX9K/T6YiMjGTQoEG88cYblbozjEYjL7zwAl999RUffvght99+O3a7nXbt2jF79mwKCgq45557WL16NXPnzvW1IlZl+PDhXHzxxXWaE+d4jz76KJ07d+aTTz7h1VdfJT4+nksuuYTrrruuQa0W7du354MPPuDNN9/kq6++4pVXXvGNaHnmmWc466yzfPveeeedOJ1Onn/+eRwOB0lJSVx77bXs3buXn376qcak3FGjRjFmzBieeeYZ/vzzT1555ZV6lfOGG24gNjaWd955hw8++IDIyEimTJnCjTfeWG0+zI033khcXBzvvfcer732GhEREYwePZqbb76ZsLCwWq958sknExYWRseOHX1dQqJlUjRZRUqc4LwJveVn9ywoKGDMmDHcfvvtlRLqRMN5A9CGfAif6DZt2sRvv/3G9ddf39xFEaJNkRYVccLbtm0b8+fP5+abb6Z///7k5eXxxhtvEBYWVmnIoxANNWjQIAYNGtTcxRCizZFARZzwrrjiChwOB//73/9ITU0lODiYkSNH8vjjj8u6QUIIcYKTrh8hhBBCtFgyPFkIIYQQLZYEKkIIIYRosSRQEUIIIUSLJYGKEEIIIVqsVjHqR9M0VNX/OcE6nRKQ84rKpK6bltR305G6bjpS103HH3Wt0yl1WrqgVQQqqqqRk1O3heLqymDQERUVQkFBCS5X065d09ZIXTctqe+mI3XddKSum46/6jo6OgS9vvZARbp+hBBCCNFiSaAihBBCiBZLAhUhhBBCtFgSqAghhBCixWoVybR14RkZpKKq1S9VXp6qKthsehwOO263ZJEHktR13ej1BnQ6+W4hhGhbWn2gomkaVmsRRUX5dQ5SvLKydKiqZI83BanrugkKCiU8PLpOQ/qEEKI1aPWBSkFBDlZrERZLCBZLMDqdvs5v8nq9It/wm4jUdc00TcPhsFNUlAtARERMM5dICCGaRqsOVFTVjdVaTGhoJKGhEfU+3mDQyXj8JiJ1XTuTyQxAUVEuYWFR0g0khGgTWvU7ndvtBjTMZktzF0UIv/AGK263q5lLIoQQTaNVByplpD9ftA6SmyKEaGvqHajk5eVx//33M2HCBIYOHcq///1v1q1b53v8zz//5Nxzz2XQoEFMmTKF5cuXVzje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lMskhGh+VntZd6LF1KpXWDlh6HU6erQPZ9vBXPak5FUKVPakeHoGenaMbIbSNY163YkHDhzgscce4/TTT+fqq68mKyvL95jFYmHWrFnMmDGDefPmMWPGDFauXMm3337La6+9BkBCQgJnn3029957L4899hhBQUE88MADjBw5ksGDB/v1idVGURTMppq/MRgMOvS6ltP0Uj4JWdM8AcRLL71KcHDFRGLvGjBDhgzHaDSyYcPfrFu3hsmTz6Jdu3YsW/YhaWmp7Nmzm0cf9SRHf/fdtzz66AOcccaZDBiQzPTp57J//z6effbJasvgbZbylsXLYCi7rSIjI3njjffYunUza9euZvXqP/noo/8xe/bVXH75fxpXIUIIv7I6PN0+ZpMeXQt672vreiZFlgYq+UwamlThsd1H8kr3qf96dieKegUqK1aswOl08v333/P9999XeGzGjBk88cQTLFy4kKeffpo333yTpKQknn76aV/rCcDcuXN57LHHuP766wGYMGEC9957rx+eStvStWt3ALKzs+jVq49v++LFL6HX67nyymswGAyMHDmaVatWsn37Vu6++wFiY2Nxu90sWbKYbt160K6dJznr3XeXcs45/+DWW+/yneu331YCnpyeqlqAOnXqjMlkZvPmTb7uJ5fLxZ49uxk61DNPznfffUNhYSHnnXcBycmDmT37ap588hF+/PE7CVSEaGG8+SlBtXyJE03LG4TsScmrsN3pcnMgtQCAXkmRTVyqplOvQOWaa67hmmuuqXGfCRMmMGHChGofDw4O5pFHHuGRRx6pz6XFcbp1686YMeN5+unHufnmO+jatRu//PIj77yzlLvvfsC337hxE3jyyUeIjY2jQwdPJD5gQDIrVnzNJZdc4dsvPj6BLVs2sWvXTkJDQ1m1aiXLln0IeBKijx9SDp7X8vzzL+D11xcTGxtLly7d+N//3iYrK9O3j8Nh56WXXiAkJIRBg4aQkZHBhg1/M3iwTO4nREvj7foJMku3T0vSrX0Eep1CToGdrHwrsRGewScH0wpxuTXCg43EB2C0T0shd+MJ7OGHH+eVV17i6acfo7CwgPbtk7jzzvs488ypvn1Gjx6L2+32tXAADB8+kr//Xse4cWVz4tx00+089dSjXH/9VZhMRnr06MW99z7EAw/czc6d2xk0qOrA4uqrr8dkMvPss09SUlLCpEmnM3ZsWaA6deo/yM/PZ+nS18jISCcsLIyJE0/l2mtl2QQhWhpfi4oEKi2K2aSnU0IYB1IL2JOS7wtUfPkpSZGtesFSRWsFU/i53So5OcWVtjudDrKzU4mJaYfRWP9s6EAl04rKpK7rprH3NLTeYZwt0YlW179vSWXJ8h307xrNLRcObu7i1MuJVtf19f6Pe/hu7REmDunAJZM9Xe3Pf7SJzfuy+depPTljRMdaztAwanEuOO3oIssGQPirrqOjQwI7j4oQQojWxVY6BbvkqLQ8PZMi+W7tEV+eiqpp7PW1qPgvkVYtycN9bCfuYztwHduJVpAOQPD5c9FHByYYqo0EKkIIIQAoka6fFqtnR08wcjSzmCKrk7wiOyV2F2ajnk4JobUcXT3N7cSdtgfXkS24U7ag5qRU3EFR0Lfrgy44quoTNAG5G4UQQgBgk0ClxQoPNpEYHUxaTgl7j+b7ljro1j4cva5+66Sp1gLchzfhOvg3rqPbwFV+xngFXUwn9O37YGjfB31iLxRz5bX0mpLcjUIIIYCyZFqLdP20SD2TIkjLKWFPSh65BZ718XrVcaI3tSgb1/51uA79jTttd4U1S5SgcPRJAzF0HIg+qT86S1ggit9gEqgIIYQAwFqaoxIsLSotUs+kSH7bnMqelLIWlZryU1RrAa79a3HtW+0JTsrRxXTC0GUohs5D0MV0RFFa7ur1cjcKIYQAyrWoSKDSIvUqzVPZdzQfTQOdotCtfXiFfTS3E9ehDTh3/YY7ZRv4Zg5X0Cf2xNBthCc4CYtt4tI3nNyNQgghgLJARVpUWqa4SM/Cg/nFnpySTgmhvjWZ3NlHcO76FdeeP9HsRb5jdHFdMXYfhaHbSHSh0c1S7saSu1EIIQRQNjOtRVZObpEURaFnUgTrdnlm/+7VIQzn3r9wbPsBNX1v2X4hURh7jcPYayy6iBN/AVgJVIQQQgDl1/qRj4aWQtNUtMIsUN1oaAyMc3J0by4DjUeYfPRTbAcKPTsqegxdhmDsPQF90gCUeo4EasnkbhRCCAGAzSHDk1sKTXXh2rsax8blqHnHfNsHA4O9+bMOUIIiMPY7BWPfieiCI5uhpIHXekIu0eRcLhcffPCu7/clSxZz/vnn+P06gTpvc2hNz0W0LpqmyaKELYDmcuDY9gPF79+B7ZdXPUGKzgDmEN8/h85CblBHLJOuJuSiZzAP+0erDVJAWlREI3z//be8+OJzXHjhzOYuihCikRxOFbV0bo0gyVFpcprbiXPHShwbvkCzFgCe+U2MA8/A1G8Siim4wv4xzVHIZiKBimiwVrCepRCilLW020cBzEYJVJqKpqq49v6Bff1nnlwUQAmNwTToTIy9J6AYGrb4aGvSZgMVTdOOmza4qn10aIFYhdNgqveS3H/++TuvvbaIgwf3ExQUzOjRY7nhhpsJDw/n77/XcdNN/+Xhh59g0aIXSU9PZ8CAgdxzz4P8739v8+23yzEYjPzzn//i0ktn+875zTdf8f7773LkyGGio6OZOnU6s2Zdjl7veZNKT09j8eKXWLduDSUlxSQnD+a66/6PHj168vXXX/LYYw8BMG7ccObPX+Q77zvvLOWTTz4kPz+f/v0HcPvt99CxYycAioqKeOmlF/jtt59xOp307t2X666bw4ABA3zHf/75Mt577y0yMzMZMWIk7dq1r7Furr/+Kjp27Mzevbs5cuQQN998B2eccSbLl3/Be++9RWpqKu3atWP69PM4//wLAZg2bTIXX3wp//rXxQB8+OH/mD//GV577S369OkHwD333EZYWDh33nkfmzZtYMmSxezcuQOn00H79h245JIrmDz5LAAeffRBrFYrxcVFbNu2lUsvvYKZMy+t9bnU9LoK0ZTKz6FS3/cnUX+apuE+vAn7mg9Rcz05KEpwJKah0zD2mYCia7Mfz5W0yZrQNI2SLx6tMJyrKekTehI07e46vxnk5eVxzz23cf31NzFmzDgyMtKZO/cBFi58gTvvvA8At9vNW2+9zgMPPILL5eK2227ksssuYurU6bzyypt89903vPrqy4wbdzLdu/fgww/fY9GiBVx//U2MGDGK7du38uyzT5Kfn8///d8tlJQUc+21s2nfvgNPPPEMRqOJ119/heuv/w9Ll/6PU089naKiIubPf4bPP/+W8PAINmxYT1paKlu2bOLpp1/A6XQwd+79PPHEXF566VU0TeO22+ZgMll48snnCQ0N5dtvl3PttbN57bU36d69F99//y3PPvsk//d/tzJ8+Eh+/fVnXnllIfHxCTXW0VdffcZ9982lR48exMTE8vnny1i8+CVuvvl2+vbtz549u3juuafIysrguuv+j9Gjx7J27RpfoLJu3WoUReHvv9fRp08/XC4Xa9eu4f7755KZmcHNN1/PeeddyO2334PT6eTdd9/kiSfmMmLEKKKjPY2wv/zyI9ddN4ebbrods9lc63Opy+sqRFPx5qcES7dPwKl5qdj+/B/uI5s9G8whmAadjWnAqSgGc/MWrgVqk4EKgMKJ840hMzMdh8NBQkIiiYntSExsx5NPPovb7a6w35VXXuNrDRg2bATbt2/luuvmoCgKs2ZdxtKlr7F//166devOO++8ybnnXsC55/4TgI4dO5Gfn8/ChS8we/bVfP/9t+Tn57FkyTtERXlWzXzwwUe44IJ/sGzZh1x33f8RGupZsTMmpmyGQ4PBwP33zyUkxPPY9Onn8sorCwFYv34tW7duYfnyHwgP96StX331f9myZRMffPA/7r77AT7++ANOO+0MX7kuvvgytm3bwp49Fad/Pl7Pnr0444wpvt/ffHMJl102m9NOmwxAhw5JFBcX88wzTzJ79jWMGzeBuXPvx+FwoNPp2LDhb8aNO5m//17HRRddwsaNf6OqbkaMGElWVhazZ1/Nv/89yxdczpp1Od9+u7y0NcoTqISFhXPRRZf4ylDbc6nr6ypEU/B2/cistIGjOazY//4c55bvQXODTo9p4GRMg89u9oX/WrI2eUcqikLQtLtr7foxGHS4WkDXT8+evTnttMncccdNxMTEMmLEKMaMGc+ECRMr7JeU1NH3c1BQEO3atfddx2y2AOB0OsnLyyUnJ5vk5MEVjh8yZCgul4tDhw6yb99eOnbs7AtSvOfo168/+/btq7as0dExviAFPB/edrtn8azdu3eiaRrnnTe1wjEOhwOHw/Na7N+/1xdceA0YkFxroJKU1Mn3c25uLhkZ6Sxa9BKvvvqyb7uqqjgcdlJTjzFixEmoqsqWLZvQ6/UEBwcxffq53HffnbhcLv78cxUjRpyE2WyhQ4ckzjprGh999D779+8lJeUIe/fuAagQVJSv/7o8l7q+rkI0BatNhiYHknP/Wuy/v4NmzQdA32kQltH/bhUTsgVam70jFUUBY81NbIpBh6IEIFBpgAcffJQrrvgPf/31B2vXrmbu3PtITh7MCy+UfRAbDBVfzuqCoeqSYFVVK3ee6vZRMRiqbxrW1TDJkKqqhISEsGTJO5UeCwryvhYKmlaxzo9/XlUxm8teS+/xc+bcxPDhoyrtm5CQiNFoZMiQ4axZ8xdGo5GhQ0cwaNAQXC4nO3du548/VjFr1uUAHDiwn+uuu5LevfswYsQoTj75FCIjo/jPfy6ttgx1fS51eV2FaAreFhWZ7M2/1JI87KvexnVwPQBKRAKW0Rdh6DSomUt24pB5VE4A27ZtZf78Z+jUqQsXXHARTz/9AnfddT/r168lNzen3ueLjo4hOjqGzZs3Vti+adMGjEYjHTok0b17T44cOVTh/Ha7nZ07d9ClSzeg+kCoOt269aC4uBin00lSUkffv3fffZNff/0F8HThbN68qcJxO3fuqNd1oqKiiYyM4tixoxWus2vXDl59daEvUBs7djxr1/7F33+vY9iwEQQFBdG//0A+/3wZx44dZcyY8QB8/vknREdH8/zzC5k581JGjx5HdnZ2reWo7bn4+3UVojHK5lCRHBV/0DQN567fKP7wbk+QougxDZ1GyPmPSJBSTxKonABCQkJYtuwjFi6cT0rKEfbv38uPP35HUlInIiIiG3TOf/97FsuWfcinn35MSsoRvvvuW15//RWmTZtBaGgop58+hYiISO6770527NjG3r17ePjhe7FarUyffi7g6V4Cz4ev3W6r9ZqjRo2mZ89ePPDAXfz99zpSUo7w4ovP8vXXX9K1qyf4ufjiy/j115957723OHLkMB9//D6//PJjvZ6boijMnHkpH3/8AZ988gFHj6awcuXPzJv3BGazBZPJM9xv7Njx7N27h+3btzJ8+EjAk9uzYsXXDBiQTGRkJADx8QlkZKTz55+/k5aWysqVP/HMM08A+LqsqlLbcwnE6ypEQ9ns0vXjL2pJPtZvn8O2cgk4StDFdiH43AcwDz8XRW9s7uKdcOSOPAF06dKVRx99mjfeeJVPP/0InU7H0KEjeOaZ+TV2tdTk3/++GJPJyAcfvMcLL8wjPj6BmTMv5aKLZgEQGhrKiy8uZsGC5/m//7sOgOTkQbz88hLat+8AwNChI+jXbwDXXnsF9903t9Zr6vV6nntuIQsXvsD999+J1WqlS5duPPro0wwfPhKXS2XMmHE88MAjvP76K7z22iL69x/Iv/51Md9//229n5/ZbObjj9/nxRefIzo6hmnTZjB79tW+fRISEune3dPKk5jYDoDhw0eyZMlixo072bff+ef/i0OHDjJ37v04nU46duzIVVddx+uvv8LOnds56aQxVZahtucSiNdViIYqkXV+/MJ1ZAu2X171TNqmN2Aa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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "import os\n",
    "\n",
    "def smooth(data: list, weight: float = 0.9):\n",
    "    '''用于平滑曲线，类似于Tensorboard中的smooth曲线\n",
    "    '''\n",
    "    last = data[0] \n",
    "    smoothed = []\n",
    "    for point in data:\n",
    "        smoothed_val = last * weight + (1 - weight) * point  # 计算平滑值\n",
    "        smoothed.append(smoothed_val)                    \n",
    "        last = smoothed_val                                \n",
    "    return smoothed\n",
    "\n",
    "def plot_rewards(cfg, frames, rewards):\n",
    "    ''' 画图\n",
    "    '''\n",
    "    sns.set_theme(style=\"darkgrid\")\n",
    "    plt.figure()  # 创建一个图形实例，方便同时多画几个图\n",
    "    plt.title(f\"{cfg.mode}ing curve on {cfg.device} of {cfg.algo_name} for {cfg.env_id}\")\n",
    "    plt.xlabel('frames')\n",
    "    plt.plot(frames, rewards, label='rewards')\n",
    "    plt.plot(frames, smooth(rewards), label='smoothed rewards')\n",
    "    plt.legend()\n",
    "    plt.show()\n",
    "\n",
    "def print_cfgs(cfg):\n",
    "    ''' 打印参数\n",
    "    '''\n",
    "    cfg_dict = vars(cfg)\n",
    "    print(\"Hyperparameters:\")\n",
    "    print(''.join(['=']*80))\n",
    "    tplt = \"{:^20}\\t{:^20}\\t{:^20}\"\n",
    "    print(tplt.format(\"Name\", \"Value\", \"Type\"))\n",
    "    for k,v in cfg_dict.items():\n",
    "        if v.__class__.__name__ == 'list':\n",
    "            v = str(v)\n",
    "        print(tplt.format(k,v,str(type(v))))   \n",
    "    print(''.join(['=']*80))\n",
    "\n",
    "def all_seed(seed: int = 0):\n",
    "    ''' 设置随机种子\n",
    "    '''\n",
    "    if seed == 0:\n",
    "        return\n",
    "    np.random.seed(seed)\n",
    "    random.seed(seed)\n",
    "    torch.manual_seed(seed) # config for CPU\n",
    "    torch.cuda.manual_seed(seed) # config for GPU\n",
    "    os.environ['PYTHONHASHSEED'] = str(seed) # config for python scripts\n",
    "    # config for cudnn\n",
    "    torch.backends.cudnn.deterministic = True\n",
    "    torch.backends.cudnn.benchmark = False\n",
    "    torch.backends.cudnn.enabled = False  \n",
    "\n",
    "# 获取参数\n",
    "cfg = Config() \n",
    "all_seed(cfg.seed)\n",
    "print_cfgs(cfg)\n",
    "res = train(cfg)\n",
    "plot_rewards(cfg, res['frames'], res['rewards'])\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.6.9 64-bit",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.14"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
